﻿using System;
using System.IO;
using System.Xml;

namespace openxmlconv
{
    
    public static class OdfParser

    {
        public static Document Parse(Stream s)
        {
            XmlReader reader = new XmlTextReader(s);
            Document d = new Document();            

            while (true)
            {

                if (reader.NodeType == XmlNodeType.Element)
                {
                    Console.WriteLine("element " + reader.LocalName);
                    switch (reader.LocalName)
                    {
                            
                        case "p":
                            ParseParagraph(reader, d);
                            break;
                        case "style":
                            ParseStyle(reader, d);
                            break;
                        case "span":
                            ParseSpan(reader, d);
                            break;
                        default:
                            reader.Read();
                            break;
                    }
                }
                else
                {

                    switch (reader.NodeType)
                    {
                        case XmlNodeType.Text:
                            ParseSpan(reader, d);
                            break;
                        default:
                            reader.Read();
                            break;
                    }
                    if (reader.LocalName == "document-content" && reader.NodeType == XmlNodeType.EndElement)
                        return d;
                }
            }
            return d;
        }

        private static void ParseSpan(XmlReader reader, Document d)
        {
            String styleName = reader.GetAttribute("text:style-name");
            Style runStyle = null;
            String s = reader.ReadString();
            Console.WriteLine(s);
            Run run = new Run(s);
            if (styleName != null)
                runStyle = d.GetStyleTable().Query(styleName);
            run.SetStyle(runStyle);
            d.Add(run);
        }
        private static void ParseParagraph(XmlReader reader, Document d)
        {
            String styleName = reader.GetAttribute("text:style-name");
            Style paragraphStyle = null;            
            if (styleName != null)
                paragraphStyle = d.GetStyleTable().Query(styleName);
            String s = reader.ReadString();
            Console.WriteLine(s);
            Run run = new Run(s);
            Paragraph p = new Paragraph(run);
            p.SetStyle(paragraphStyle);
            d.AddParagraph(p);
        }
        private static void ParseStyle(XmlReader reader, Document doc)
        {
            
            String name = reader.GetAttribute("style:name");
            String family = reader.GetAttribute("style:family");
            String parentStyle = reader.GetAttribute("style:parent-style-name");

            reader.Read();
            Console.WriteLine(reader.LocalName);

            if (reader.LocalName == "text-properties")
            {                
                Style style = RunStyle.create(name, family, parentStyle);
                ParseRunStyleAttributes(reader, style);
                doc.GetStyleTable().add(style);
            }
            else if (reader.LocalName == "paragraph-properties")
            {        
                Style style = ParagraphStyle.create(name, family, parentStyle);
                ParseParagraphStyleAttributes(reader, style);                
                doc.GetStyleTable().add(style);
            }
            
            return;
        }

        private static void ParseParagraphStyleAttributes(XmlReader reader, Style style)
        {        
            style.setAlignment(ParseAlignment(reader));                
        }

        private static void ParseRunStyleAttributes(XmlReader reader, Style style)
        {
            if (ParseBold(reader))
                style.setBold();
            if (ParseItalic(reader))
                style.setItalic();
            if (ParseUnderline(reader))
                style.setUnderline();
            style.setFontName(ParseFontName(reader));
            style.setFontSize(ParseFontSize(reader));
        }
        
        private static string ParseAlignment(XmlReader reader)
        {
            return "end";
        }
        private static int ParseFontSize(XmlReader reader)
        {
            String fontSize = reader.GetAttribute("fo:font-size");
            if (fontSize != null)
            {
                fontSize = fontSize.Substring(0, fontSize.Length - 2);
                return Convert.ToInt32(fontSize);
            }
            return 12;
        }
        private static bool ParseItalic(XmlReader reader)
        {
            String value = reader.GetAttribute("fo:font-style");
            return (value == "italic");
        }
        private static Boolean ParseBold(XmlReader reader)
        {
            String value = reader.GetAttribute("fo:font-weight");                                        
            return (value == "bold");
        }
        private static Boolean ParseUnderline(XmlReader reader)
        {
            String value = reader.GetAttribute("style:text-underline-style");
            return (value == "solid");
        }
        private static string ParseFontName(XmlReader reader)
        {
            String fontName = reader.GetAttribute("style:font-name");
            return fontName;
        }

    }
}
